package org.lcc.mapper;

import org.apache.ibatis.annotations.*;
import org.lcc.model.VO.*;
import org.lcc.model.dto.ManualDto;
import org.lcc.model.dto.SubjectiveAnswerDto;
import org.lcc.model.entity.*;
import org.lcc.model.entity.Class;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Mapper
public interface ExaminationmanagementMapper {
    //创建考试基本信息
    Integer createExam(Exam exam);

    //查询题库
    List<QuestionVO> getQuestionSummaryBySchoolNumber(@Param("schoolNumber") String schoolNumber);

    //查询题库各类题型数量等信息
    List<QuestionDataVo> getNumberOfDifferentTypes(@Param("questionName") String questionName);

    //随机获取题目
    List<Integer> randomQuestion(@Param("questionName") String questionName, @Param("type") String type, @Param("difficulty") String difficulty, @Param("needCount") int needCount);

    //插入到exam_question考试试题表中
    Integer insertExam_question(@Param("examId") Integer examId, @Param("questions") List<Integer> questions, @Param("score") Integer score);

    ////根据题库题型显示题目供用户手动选择
    List<ManualDto> getManualQuestionsByQuestionName(@Param("questionName") String questionName);

    //发布考试
    int batchInsert(List<ExamReleaseentity> examReleaseList);

    //查询学生是否存在
    List<String> getExistingStudentIds(List<String> targetId);

    //通过学号来查询邮箱和姓名
    @MapKey("email")
    List<Map<String, String>> getRecipientsEmailAndName(List<String> targetId);

    //通过班级来查询学生学号
    List<String> getstudent_class_link(List<String> targetId);

    //更新考试基本信息表里面的状态
    int updateExamStatus(@Param("status") String status, @Param("examId") Integer examId);

    // 获取所有状态有效且即将开始的考试
    List<Exam> selectUpcomingExams(@Param("now") LocalDateTime now);

    // 查询特定考试、学生和通知类型的数量
    int selectNotificationCount(@Param("examId") Integer examId,
                                @Param("studentId") String studentId,
                                @Param("notificationType") String notificationType,
                                @Param("status") boolean status);

    // 插入通知记录
    int insertNotification(ExamNotification notification);

    //获取指定考试的学生ID
    List<String> getStudentIdsForExam(Integer examId);

    //获取考试时间已过的考试
    List<Exam> seletEffectiveness(@Param("now") LocalDateTime now);

    // 获取当前时间恰好为考试时间的考试
    List<Exam> selectPunctuality(LocalDateTime now);

    //通过schoolNumber来到exam_release表里面有关系的考试场次
    List<Integer> getExam_release(@Param("schoolNumber") String schoolNumber);

    //通过examId来到exam表里面有关系的考试场次
    ExamVO selectExamById(@Param("examId") Integer examId);

    //通过schoolNumber来到Student_class_link表里面对应的班级
    List<Integer> getStudent_class_link_clasId(@Param("schoolNumber") String schoolNumber);

    //通过班级ID列表查询考试ID列表
    List<Integer> getExam_releaseList(List<String> studentClassLinkClasIdStr);

    //通过考试id(examId)去查询到具体的考试试题
    List<Question_onlineExamVO> getExamQuestionList(Integer examId);

    //获取考试基本信息
    Exam getExamById(@Param("examId") Integer examId);

    ////考生的答案提交
    int insertStudentAnswer(StudentAnswerEntity studentAnswerEntity);

    ////查询到试题答案和该题的分值
    Map<String, Object> select_exam_question_answer(@Param("questionId") Integer questionId, @Param("examId") Integer examId);

    //获取该考生该考试的客观题总分
    Integer getTotal_objective_score(@Param("schoolNumber") String schoolNumber, @Param("examId") Integer examId);

    //插入到exam_record（考试记录表）
    int insertExamRecord(
            @Param("examId") int examId,
            @Param("schoolNumber") String schoolNumber,
            @Param("objectiveScore") int objectiveScore,
            @Param("subjectiveScore") int subjectiveScore,
            @Param("totalScore") int totalScore,
            @Param("status") String status,
            @Param("submitTime") LocalDateTime submitTime,
            @Param("uniqueIdentifier") String uniqueIdentifier
    );

    //查询到该考试下的所有学生
    List<String> seletExam_record_student_id(Integer examID);

    //通过学生ID 和 考试ID 查询到该学生的客观题答案
    List<Subjective_questionEntity> getSubjectiveAnswers(@Param("examID") Integer examID, @Param("studentID") String studentID);

    //通过题目ID查询题目内容
    String getQuestionContent(Integer questionId);

    //人工评卷后对其数据库更新
    int updatestudent_answer_batch(@Param("list") List<SubjectiveAnswerDto> subjectiveAnswerDtoList);

    //更新exam_record表里面的状态和得分
    int updateSubjectiveScore(
            @Param("status") String status,
            @Param("score") int score,
            @Param("examId") int examId,
            @Param("schoolNumber") String schoolNumber
    );
    // 获取教师创建的所有班级
    List<Class> getTeacherClasses(@Param("teacherId") String teacherId);

    // 获取教师所有班级中的学生
    List<StudentVO> getTeacherStudents(@Param("teacherId") String teacherId);
    //查询试题详情
    Question getQuestionById(Integer questionId);
    // 通过考试ID获取试题ID
    @Select("SELECT question_id FROM exam_question WHERE exam_id = #{examId}")
    List<Integer> getQuestionIdsByExamId(Integer examId);
    //通过试题ID和试卷ID来查询该题的分值
    @Select("SELECT score FROM exam_question WHERE question_id = #{questionId} AND exam_id = #{examId}")
    Integer getQuestionScore(@Param("questionId") Integer questionId,@Param("examId") Integer examId);

    // 获取考试状态
    @Select("SELECT status FROM exam WHERE exam_id = #{examId}")
    String getExamStatus(@Param("examId") Integer examId);

    // 插入考试学生关联
    @Insert("<script>" +
            "INSERT INTO exam_release (exam_id, target_type, target_id) VALUES " +
            "<foreach collection='studentIds' item='studentId' separator=','>" +
            "(#{examId}, 'student', #{studentId})" +
            "</foreach>" +
            "</script>")
    int insertExam_student(@Param("examId") Integer examId, @Param("studentIds") List<String> studentIds);
    // 通过教师ID获取考试信息
    List<ExamVO> getteacherIdExam(@Param("teacherId") String teacherId, @Param("status") String status,@Param("searchText") String searchText);
    // 通过考试ID获取考试详情
    ExamVO getExamDetail(@Param("examId") Integer examId);
    // 更新考试信息
    int updateExamInfo(Exam exam);

    // 获取考试试题列表
    List<QuestionPreviewVocopy> getExamQuestions(@Param("examId") Integer examId);

    @Select("SELECT DISTINCT question_name as questionName FROM question WHERE creator_id = #{teacherId}")
    List<QuestionVO> getQuestionBanks(@Param("teacherId") String teacherId);

    /**
     * 获取指定题库中的所有试题
     */
    @Select("SELECT * FROM question WHERE question_name = #{questionBankName}")
    List<Question> getQuestionsByBank(@Param("questionBankName") String questionBankName);
    //添加试题
    @Insert("INSERT INTO exam_question(exam_id, question_id, score) VALUES(#{examId}, #{questionId}, #{score})")
    int insertExamQuestion(@Param("examId") Integer examId,
                           @Param("questionId") Integer questionId,
                           @Param("score") Integer score);
    /**
     * 根据考试ID和试题ID查询关联记录
     */
    @Select("SELECT * FROM exam_question WHERE exam_id = #{examId} AND question_id = #{questionId}")
    ExamQuestion selectByExamAndQuestionId(@Param("examId") Integer examId, @Param("questionId") Integer questionId);
    /**
     * 根据考试ID和试题ID删除关联记录
     */
    @Delete("DELETE FROM exam_question WHERE exam_id = #{examId} AND question_id = #{questionId}")
    int deleteByExamAndQuestionId(@Param("examId") Integer examId, @Param("questionId") Integer questionId);
    /**
     * 删除考试-试题关联
     */
    @Delete("DELETE FROM exam_question WHERE exam_id = #{examId}")
    void deleteExamQuestions(@Param("examId") Integer examId);

    /**
     * 删除考试-发布关联
     */
    @Delete("DELETE FROM exam_release WHERE exam_id = #{examId}")
    void deleteExamReleases(@Param("examId") Integer examId);

    /**
     * 删除考试记录
     */
    @Delete("DELETE FROM exam_record WHERE exam_id = #{examId}")
    void deleteExamRecords(@Param("examId") Integer examId);

    /**
     * 删除考试基本信息
     */
    @Delete("DELETE FROM exam WHERE exam_id = #{examId}")
    void deleteExam(@Param("examId") Integer examId);
    //获取最近五场考试

    List<Exam> selectRecentExams(String schoolNumber);
    void updateById(Exam exam);
    List<Exam> selectExamsExcludeStatus(@Param("statusList") List<String> statusList);
    List<ExamRecordoneVO> getExamstudentAnswer(@Param("schoolNumber") String schoolNumber);
    //处理没有主观题的评卷情况
    Integer updateExamStatusNull(@Param("examId") String examId, @Param("schoolNumber") String schoolNumber);
    //获取当前试卷错误题
    List<StudentMistakeEntity> setAlistwrongquestions(@Param("examId") Integer examId,@Param("schoolNumber") String schoolNumber);

    List<StudentMistakeEntity> selectmistake_collection(@Param("schoolNUmber") String schoolNumber);
    // 插入新的错题记录
    Integer insertMistakeCollection(ProcessedMistakeVO mistakeVO);

    // 更新已存在的错题记录
    Integer updateMistakeCollection(ProcessedMistakeVO mistakeVO);

//作弊更新成绩为0
    @Update("UPDATE student_answer SET score = 0 WHERE exam_id = #{examId} AND school_number = #{studentId}")
    void updateScoresToZero(@Param("examId") Long examId, @Param("studentId") String studentId);

//更新考试人数
    @Update("UPDATE exam SET expected_participants = #{uniqueCount} WHERE exam_id = #{examId}")
    void updateexpected_participants(@Param("examId") Integer examId,@Param("uniqueCount") int uniqueCount);
//更新考试已提交人数
    @Update("UPDATE exam SET submitted_participants = submitted_participants + 1 WHERE exam_id = #{examId}")
    int updateExamSubmittedParticipants(@Param("examId") Integer examId);

    //通过examId来查询考试信息，返回ExamListVo
    ExamListVo selectExamByIdForList(@Param("examId") Integer examId);
    
    /**
     * 获取学生的考试记录
     * @param examId 考试ID
     * @param studentId 学生ID
     * @return 考试记录
     */
    ExamRecord getStudentExamRecord(@Param("examId") Integer examId, @Param("studentId") String studentId);
}
